#ifndef _SCULL_H_ 
#define _SCULL_H_ 
 
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */ 
 
/* 
 * Macros to help debugging 
 */ 
 
#undef PDEBUG             /* undef it, just in case */ 
#ifdef SCULL_DEBUG 
#  ifdef __KERNEL__ 
     /* This one if debugging is on, and kernel space */ 
#    define PDEBUG(fmt, args...) printk( KERN_DEBUG "scull: " fmt, ## args) 
#  else 
     /* This one for user space */ 
#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) 
#  endif 
#else 
#  define PDEBUG(fmt, args...) /* not debugging: nothing */ 
#endif 
 
#undef PDEBUGG 
#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */ 
 
#ifndef SCULL_MAJOR 
#define SCULL_MAJOR 0   /* dynamic major by default */ 
#endif 
 
#ifndef SCULL_NR_DEVS 
#define SCULL_NR_DEVS 4    /* scull0 through scull3 */ 
#endif 
 
#ifndef SCULL_P_NR_DEVS 
#define SCULL_P_NR_DEVS 4  /* scullpipe0 through scullpipe3 */ 
#endif 
/* 
 * The bare device is a variable-length region of memory. 
 * Use a linked list of indirect blocks. 
 * 
 * "scull_dev->data" points to an array of pointers, each 
 * pointer refers to a memory area of SCULL_QUANTUM bytes. 
 * 
 * The array (quantum-set) is SCULL_QSET long. 
 */ 
#ifndef SCULL_QUANTUM 
#define SCULL_QUANTUM 4000 
#endif 
 
#ifndef SCULL_QSET 
#define SCULL_QSET    1000 
#endif 
 
/* 
 * The pipe device is a simple circular buffer. Here its default size 
 */ 
#ifndef SCULL_P_BUFFER 
#define SCULL_P_BUFFER 4000 
#endif 
 
/* 
 * Representation of scull quantum sets. 
 */ 
struct scull_qset { 
  void **data; 
  struct scull_qset *next; 
}; 
 
#define SCULL_DATA_SIZE     16 
 
struct scull_dev { 
  char data[SCULL_DATA_SIZE]; /* Pointer to first quantum set */ 
  unsigned long size;         /* amount of data stored here */ 
  struct semaphore sem;       /* mutual exclusion semaphore     */ 
    struct cdev cdev;      /* Char device structure    */ 
}; 
 
/* 
 * Split minors in two parts 
 */ 
#define TYPE(minor) (((minor) >> 4) & 0xf)  /* high nibble */ 
#define NUM(minor)  ((minor) & 0xf)   /* low  nibble */ 
 
 
/* 
 * The different configurable parameters 
 */ 
extern int scull_major;     /* main.c */ 
extern int scull_nr_devs; 
extern int scull_quantum; 
extern int scull_qset; 
 
extern int scull_p_buffer;  /* pipe.c */ 
 
 
/* 
 * Prototypes for shared functions 
 */ 
 
int     scull_p_init(dev_t dev); 
void    scull_p_cleanup(void); 
int     scull_access_init(dev_t dev); 
void    scull_access_cleanup(void); 
 
int     scull_trim(struct scull_dev *dev); 
 
ssize_t scull_read(struct file *filp, char __user *buf, size_t count, 
                   loff_t *f_pos); 
ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, 
                    loff_t *f_pos); 
loff_t  scull_llseek(struct file *filp, loff_t off, int whence); 
int     scull_ioctl(struct inode *inode, struct file *filp, 
                    unsigned int cmd, unsigned long arg); 
/* 
 * Ioctl definitions 
 */ 
 
/* Use 'k' as magic number */ 
#define SCULL_IOC_MAGIC  'k' 
/* Please use a different 8-bit number in your code */ 
 
#define SCULL_IOCRESET    _IO(SCULL_IOC_MAGIC, 0) 
 
/* 
 * S means "Set" through a ptr, 
 * T means "Tell" directly with the argument value 
 * G means "Get": reply by setting through a pointer 
 * Q means "Query": response is on the return value 
 * X means "eXchange": switch G and S atomically 
 * H means "sHift": switch T and Q atomically 
 */ 
#define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC,  1, int) 
#define SCULL_IOCSQSET    _IOW(SCULL_IOC_MAGIC,  2, int) 
#define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC,   3) 
#define SCULL_IOCTQSET    _IO(SCULL_IOC_MAGIC,   4) 
#define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC,  5, int) 
#define SCULL_IOCGQSET    _IOR(SCULL_IOC_MAGIC,  6, int) 
#define SCULL_IOCQQUANTUM _IO(SCULL_IOC_MAGIC,   7) 
#define SCULL_IOCQQSET    _IO(SCULL_IOC_MAGIC,   8) 
#define SCULL_IOCXQUANTUM _IOWR(SCULL_IOC_MAGIC, 9, int) 
#define SCULL_IOCXQSET    _IOWR(SCULL_IOC_MAGIC,10, int) 
#define SCULL_IOCHQUANTUM _IO(SCULL_IOC_MAGIC,  11) 
#define SCULL_IOCHQSET    _IO(SCULL_IOC_MAGIC,  12) 
 
/* 
 * The other entities only have "Tell" and "Query", because they're 
 * not printed in the book, and there's no need to have all six. 
 * (The previous stuff was only there to show different ways to do it. 
 */ 
#define SCULL_P_IOCTSIZE _IO(SCULL_IOC_MAGIC,   13) 
#define SCULL_P_IOCQSIZE _IO(SCULL_IOC_MAGIC,   14) 
/* ... more to come */ 
 
#define SCULL_IOC_MAXNR 14 
 
#endif /* _SCULL_H_ */ 
